﻿using System;
using MugenInjection.Interface;
using MugenInjection.Interface.Components;
using MugenInjection.Logging.Interface;

namespace MugenInjection.Logging.Components
{
    /// <summary>
    /// Changing the log message, add class name and method name for the method that call the log method.
    /// </summary>
    public class AppendClassMethodLogMutator : LogMutatorComponent
    {
        #region Fields

        private readonly bool _addBefore;
        private readonly bool _fullClassName;
        private readonly string _pattern;

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="AppendClassMethodLogMutator"/> class.
        /// </summary>
        public AppendClassMethodLogMutator()
            : this("Class [{0}], method [{1}].")
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AppendClassMethodLogMutator"/> class.
        /// </summary>
        public AppendClassMethodLogMutator(string pattern)
            : this(pattern, true)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AppendClassMethodLogMutator"/> class.
        /// </summary>
        public AppendClassMethodLogMutator(string pattern, bool addBefore)
            : this(pattern, addBefore, false)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="AppendClassMethodLogMutator"/> class.
        /// </summary>
        public AppendClassMethodLogMutator(string pattern, bool addBefore, bool fullClassName)
        {
            _pattern = pattern;
            _addBefore = addBefore;
            _fullClassName = fullClassName;
        }

        #endregion

        #region Overrides of Component

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public override IComponent Clone()
        {
            return new AppendClassMethodLogMutator(_pattern, _addBefore, _fullClassName);
        }

        #endregion

        #region Overrides of LogMutatorComponent

        /// <summary>
        /// Changes the log message.
        /// </summary>
        /// <param name="loggerContext">The specified <see cref="ILoggerContext"/>.</param>
        public override void Mutate(ILoggerContext loggerContext)
        {
            Type declaringType = loggerContext.CallingMethod.DeclaringType;
            string pattern;
            if (declaringType == null)
                pattern = string.Format(_pattern, "NULLREFERENCE",
                                        loggerContext.CallingMethod.Name);
            else
                pattern = string.Format(_pattern, _fullClassName ? declaringType.FullName : declaringType.Name,
                                        loggerContext.CallingMethod.Name);
            loggerContext.LogMessage = string.Format(_addBefore ? "{0} {1}" : "{1} {0}", pattern,
                                                     loggerContext.LogMessage);
        }

        #endregion
    }
}